package com.pms.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pms.common.PageBean;
import com.pms.config.LocationConfig;
import com.pms.exception.BusinessException;
import com.pms.mapper.SysDeptMapper;
import com.pms.pojo.SysDept;
import com.pms.pojo.WorkAttendance;
import com.pms.mapper.WorkAttendanceMapper;
import com.pms.pojo.statistics.*;
import com.pms.service.WorkAttendanceService;
import com.pms.util.LocationUtils;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class WorkAttendanceServiceImpl implements WorkAttendanceService {

    @Autowired
    private WorkAttendanceMapper workAttendanceMapper;

    @Autowired
    private LocationUtils locationUtils;

    @Autowired
    private LocationConfig locationConfig;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public PageBean<WorkAttendance> page(
            Integer page,
            Integer pageSize,
            String userName,
            Integer operateType,
            Date startTime,
            Date endTime
    ) {
        // 设置分页参数
        PageHelper.startPage(page, pageSize);

        // 执行查询
        List<WorkAttendance> list = workAttendanceMapper.list(userName, operateType, startTime, endTime);
        Page<WorkAttendance> p = (Page<WorkAttendance>) list;

        // 封装PageBean对象，注意这里使用 rows 而不是 records
        return PageBean.<WorkAttendance>builder()
                .total(p.getTotal())
                .rows(p.getResult())  // 注意这里使用 rows
                .build();
    }

    @Override
    public WorkAttendance getById(Long id) {
        return workAttendanceMapper.getById(id);
    }

    @Override
    public void update(WorkAttendance workAttendance) {
        workAttendanceMapper.update(workAttendance);
    }

    @Override
    public void delete(Long id) {
        workAttendanceMapper.delete(id);
    }

    @Override
    public void checkIn(WorkAttendance workAttendance) {
        // 验证必要参数
        if (workAttendance.getUserId() == null || workAttendance.getOperateType() == null) {
            throw new BusinessException("缺少必要参数");
        }

        if (!Boolean.TRUE.equals(workAttendance.getIsManualInput())) {
            Integer distance = workAttendance.getDistance();
            if (distance == null || distance > locationConfig.getAllowedDistance()) {
                log.warn("打卡距离超出范围: userId={}, distance={}",
                        workAttendance.getUserId(), distance);
                throw new BusinessException("不在打卡范围内，距离办公地点: " + distance + "米");
            }
        }

        try {
            // 设置打卡时间
            workAttendance.setOperateTime(new Date());

            // 保存打卡记录
            workAttendanceMapper.insert(workAttendance);

            log.info("打卡成功: userId={}, type={}, location={}",
                    workAttendance.getUserId(),
                    workAttendance.getOperateType(),
                    workAttendance.getOperateAddress());
        } catch (Exception e) {
            log.error("打卡失败: ", e);
            throw new BusinessException("打卡失败，请稍后重试");
        }

    }

    @Override
    public List<WorkAttendance> getByUserId(Long userId) {
        if (userId == null) {
            throw new BusinessException("用户ID不能为空");
        }

        try {
            List<WorkAttendance> records = workAttendanceMapper.getByUserId(userId);
            log.info("查询到用户{}的考勤记录{}条", userId, records.size());
            return records;
        } catch (Exception e) {
            log.error("查询用户考勤记录失败: userId={}", userId, e);
            throw new BusinessException("查询考勤记录失败");
        }
    }

    @Override
    public AttendanceStatistics getAttendanceStatistics(AttendanceStatisticsQuery query) {
        log.info("开始获取考勤统计数据: {}", query);

        AttendanceStatistics statistics = new AttendanceStatistics();
        try {
            // 1. 获取基础统计数据
            if (query.getDepartmentId() != null) {
                statistics.setTotalEmployees(workAttendanceMapper.countEmployeesByDept(query.getDepartmentId()));
            } else {
                statistics.setTotalEmployees(workAttendanceMapper.countTotalEmployees());
            }

            // 2. 获取考勤率等数据
            AttendanceStatisticsData data = workAttendanceMapper.getAttendanceData(query);
            statistics.setAttendanceRate(data.getAttendanceRate());
            statistics.setLateCount(data.getLateCount());
            statistics.setAbsentCount(data.getAbsentCount());

            // 3. 获取每日考勤数据
            List<DailyAttendance> dailyStats = getDailyAttendanceStatistics(query);
            statistics.setDailyAttendances(dailyStats);

            // 4. 获取部门考勤数据
            List<DepartmentAttendance> deptStats = getDepartmentAttendanceStatistics(query);
            statistics.setDepartmentAttendances(deptStats);

            return statistics;
        } catch (Exception e) {
            log.error("获取考勤统计数据失败", e);
            throw new BusinessException("获取考勤统计数据失败");
        }
    }

    @Override
    public List<DailyAttendance> getDailyAttendanceStatistics(AttendanceStatisticsQuery query) {
        log.info("开始获取每日考勤统计数据: {}", query);
        try {
            List<DailyAttendance> dailyStats = workAttendanceMapper.getDailyAttendanceStats(query);
            log.info("获取到{}条每日考勤统计数据", dailyStats.size());
            return dailyStats;
        } catch (Exception e) {
            log.error("获取每日考勤统计数据失败", e);
            throw new BusinessException("获取每日考勤统计数据失败");
        }
    }

    @Override
    public List<DepartmentAttendance> getDepartmentAttendanceStatistics(AttendanceStatisticsQuery query) {
        log.info("开始获取部门考勤统计数据: {}", query);
        try {
            List<DepartmentAttendance> deptStats = workAttendanceMapper.getDepartmentAttendanceStats(query);
            log.info("获取到{}个部门的考勤统计数据", deptStats.size());
            return deptStats;
        } catch (Exception e) {
            log.error("获取部门考勤统计数据失败", e);
            throw new BusinessException("获取部门考勤统计数据失败");
        }
    }

    @Override
    public PageBean<AttendanceRecord> getAttendanceRecords(Integer page, Integer pageSize,
                                                           AttendanceStatisticsQuery query) {
        log.info("开始获取考勤详细记录: page={}, pageSize={}, query={}", page, pageSize, query);
        try {
            // 设置分页
            PageHelper.startPage(page, pageSize);

            // 查询记录
            List<AttendanceRecord> records = workAttendanceMapper.getAttendanceRecords(query);
            Page<AttendanceRecord> p = (Page<AttendanceRecord>) records;

            // 封装分页结果
            PageBean<AttendanceRecord> pageBean = PageBean.<AttendanceRecord>builder()
                    .total(p.getTotal())
                    .rows(p.getResult())
                    .build();

            log.info("获取到{}条考勤详细记录", pageBean.getTotal());
            return pageBean;
        } catch (Exception e) {
            log.error("获取考勤详细记录失败", e);
            throw new BusinessException("获取考勤详细记录失败");
        }
    }

}